package com.example.majiang.service;

import com.example.majiang.dto.CommentDTO;
import com.example.majiang.enums.CommentTypeEnum;
import com.example.majiang.enums.NotificationStatusEnum;
import com.example.majiang.enums.NotificationTypeEnum;
import com.example.majiang.exception.CustomizeErrorCode;
import com.example.majiang.exception.CustomizeException;
import com.example.majiang.mapper.CommentMapper;
import com.example.majiang.mapper.NotificationMapper;
import com.example.majiang.mapper.QuestionMapper;
import com.example.majiang.mapper.UserMappper;
import com.example.majiang.model.Comment;
import com.example.majiang.model.Notification;
import com.example.majiang.model.Question;
import com.example.majiang.model.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentService {
    @Autowired
    UserMappper userMappper;

    @Autowired
    CommentMapper commentMapper;
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    NotificationMapper notificationMapper;

    @Transactional
    public void insert(Comment comment,User commentor){
        if(comment.getParentId()==null||comment.getParentId()==0){
            throw new CustomizeException(CustomizeErrorCode.TARGET_PARAM_NOT_FOUND);
        }
        if (comment.getType() == null || !CommentTypeEnum.isExist(comment.getType())) {
            throw new CustomizeException(CustomizeErrorCode.TYPE_PARAM_WRONG);
        }
        //回复评论的情况
        if(comment.getType()==CommentTypeEnum.COMMENT.getType()){
            Comment dbComment=commentMapper.findByParentId(comment.getParentId());
            if(dbComment==null){
                throw new CustomizeException(CustomizeErrorCode.COMMENT_NOT_FOUND);
            }
            Question question=null;
            if(dbComment.getType()==CommentTypeEnum.QUESTION.getType()){
                question=questionMapper.getById(dbComment.getParentId());
                if(question==null){
                    throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
                }
            }


            Comment parentComment = new Comment();
            parentComment.setId(comment.getParentId());
            parentComment.setCommentCount(1);
            commentMapper.incCommentCount(parentComment);
            commentMapper.insert(comment);
            createNotify(comment, dbComment.getCommentor(), commentor.getName(), question.getTitle(), NotificationTypeEnum.REPLY_COMMENT, question.getId());
        }
        //回复问题的情况
        else{
            //此时，我们无法知道该问题是否存在。因此我们得把该问题的实体拿到手先判断再说。
            Question dbQuestion= questionMapper.getById(comment.getParentId());
            if(dbQuestion==null){
                throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
            }
            //此时问题存在。
            commentMapper.insert(comment);
            //问题评论数+1；
            dbQuestion.setCommentCount(1);
            questionMapper.updateCommentCount(dbQuestion);
            createNotify(comment,dbQuestion.getCreator(), commentor.getName(), dbQuestion.getTitle(),NotificationTypeEnum.REPLY_QUESTION, dbQuestion.getId());
        }
    }
    public List<CommentDTO> listByTargetId(Integer id,CommentTypeEnum type){
        //这个id是问题的id，那么我应该去数据库中检索到所有评论。
        Integer type0= type.getType();
        List<Comment>commentList=commentMapper.findById(id, type0);
        //此时我已检索到了所有评论，因为需要user，因此我得把所有评论中得commentor抽取出来并去重。
        if(commentList.size()==0)
            return new ArrayList<>();
        Set<Integer> commentators = commentList.stream().map(comment -> comment.getCommentor()).collect(Collectors.toSet());
        //现在，我已经拿到了所有的评论者，因此我得把所有的评论者的用户信息取出来。
        Map<Integer,User>userMap=new HashMap<>();
        User user=null;
        for(Integer commentor:commentators){
            user=userMappper.findById(commentor);
            userMap.put(commentor,user);
        }
        List<CommentDTO> commentDTOS = commentList.stream().map(comment -> {
            CommentDTO commentDTO = new CommentDTO();
            BeanUtils.copyProperties(comment, commentDTO);
            commentDTO.setUser(userMap.get(comment.getCommentor()));
            return commentDTO;
        }).collect(Collectors.toList());


        return commentDTOS;
    }
    private void createNotify(Comment comment, Integer receiver, String notifierName, String outerTitle, NotificationTypeEnum notificationType, Integer outerId) {
        Notification notification = new Notification();
        notification.setGmtCreate(System.currentTimeMillis());
        notification.setType(notificationType.getType());
        notification.setOuterid(outerId);
        notification.setNotifier(comment.getCommentor());
        notification.setStatus(NotificationStatusEnum.UNREAD.getStatus());
        notification.setReceiver(receiver);
        notification.setNotifierName(notifierName);
        notification.setOuterTitle(outerTitle);
        notificationMapper.insert(notification);
    }
}
